#!/bin/bash
# pg_dump 备份脚本

# 脚本目录路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
COMMON_DIR="${SCRIPT_DIR}/../common"

# 加载公共工具函数
source "${COMMON_DIR}/utils.sh"

# 初始化环境
LOG_FILE_PREFIX="pg_dump_backup"
init
start_timer

log_info "开始执行 pg_dump 备份..."

# 解析命令行参数
DB_NAME="${POSTGRES_DB}"
COMPRESS=true
FORMAT="custom"
VERBOSE=false

# 解析命令行参数
for i in "$@"; do
    case $i in
        --db=*)
            DB_NAME="${i#*=}"
            ;;
        --no-compress)
            COMPRESS=false
            ;;
        --format=*)
            FORMAT="${i#*=}"
            ;;
        --verbose)
            VERBOSE=true
            ;;
        *)
            log_warning "未知参数: $i，将被忽略"
            ;;
    esac
done

# 检查 PostgreSQL 连接
if ! check_postgres_connection; then
    log_error "PostgreSQL 连接检查失败，无法继续备份"
    exit 1
fi

# 检查指定的数据库是否存在
log_info "检查数据库 ${DB_NAME} 是否存在..."
if ! psql -h "${POSTGRES_HOST}" -p "${POSTGRES_PORT}" -U "${POSTGRES_USER}" -lqt | cut -d \| -f 1 | grep -qw "${DB_NAME}"; then
    log_error "数据库 ${DB_NAME} 不存在"
    exit 1
fi

# 确保备份目录存在
if [ ! -d "${PGDUMP_BACKUP_DIR}" ]; then
    log_info "创建备份目录 ${PGDUMP_BACKUP_DIR}..."
    mkdir -p "${PGDUMP_BACKUP_DIR}"
    if [ $? -ne 0 ]; then
        log_error "无法创建备份目录 ${PGDUMP_BACKUP_DIR}"
        exit 1
    fi
fi

# 设置备份文件名和路径
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILENAME="${DB_NAME}_${TIMESTAMP}"

if [ "${FORMAT}" = "custom" ]; then
    BACKUP_FILENAME="${BACKUP_FILENAME}.dump"
    FORMAT_OPTION="-Fc"
elif [ "${FORMAT}" = "plain" ]; then
    BACKUP_FILENAME="${BACKUP_FILENAME}.sql"
    FORMAT_OPTION="-Fp"
elif [ "${FORMAT}" = "directory" ]; then
    BACKUP_FILENAME="${BACKUP_FILENAME}"
    FORMAT_OPTION="-Fd"
elif [ "${FORMAT}" = "tar" ]; then
    BACKUP_FILENAME="${BACKUP_FILENAME}.tar"
    FORMAT_OPTION="-Ft"
else
    log_warning "未知格式: ${FORMAT}，使用默认的 custom 格式"
    BACKUP_FILENAME="${BACKUP_FILENAME}.dump"
    FORMAT_OPTION="-Fc"
fi

BACKUP_PATH="${PGDUMP_BACKUP_DIR}/${BACKUP_FILENAME}"

# 构建 pg_dump 命令
PGDUMP_CMD="pg_dump -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} ${FORMAT_OPTION}"

# 是否启用详细输出
if [ "${VERBOSE}" = "true" ]; then
    PGDUMP_CMD="${PGDUMP_CMD} -v"
fi

# 执行备份
log_info "开始备份数据库 ${DB_NAME} 到 ${BACKUP_PATH}..."
export PGPASSWORD="${POSTGRES_PASSWORD}"

if [ "${FORMAT}" = "directory" ]; then
    if ! ${PGDUMP_CMD} -f "${BACKUP_PATH}" "${DB_NAME}"; then
        log_error "备份失败"
        unset PGPASSWORD
        exit 1
    fi
else
    if ! ${PGDUMP_CMD} "${DB_NAME}" > "${BACKUP_PATH}"; then
        log_error "备份失败"
        unset PGPASSWORD
        exit 1
    fi
fi

unset PGPASSWORD
log_success "数据库 ${DB_NAME} 备份成功：${BACKUP_PATH}"

# 如果需要压缩（且不是已经压缩的格式）
if [ "${COMPRESS}" = "true" ] && [ "${FORMAT}" != "custom" ] && [ "${FORMAT}" != "tar" ]; then
    log_info "正在压缩备份文件..."
    if gzip -f "${BACKUP_PATH}"; then
        log_success "备份文件压缩成功：${BACKUP_PATH}.gz"
        BACKUP_PATH="${BACKUP_PATH}.gz"
    else
        log_warning "备份文件压缩失败，保留未压缩的备份文件"
    fi
fi

# 创建一个符号链接指向最新备份
LATEST_LINK="${PGDUMP_BACKUP_DIR}/${DB_NAME}_latest"
if [ -L "${LATEST_LINK}" ]; then
    rm "${LATEST_LINK}"
fi
ln -s "${BACKUP_PATH}" "${LATEST_LINK}"
log_info "创建最新备份的符号链接：${LATEST_LINK} -> ${BACKUP_PATH}"

# 清理旧备份
log_info "清理旧备份文件..."
BACKUP_COUNT=$(find "${PGDUMP_BACKUP_DIR}" -maxdepth 1 -name "${DB_NAME}_*" -not -name "*_latest" | wc -l)
if [ "${BACKUP_COUNT}" -gt "${PGDUMP_BACKUP_RETENTION}" ]; then
    EXCESS_COUNT=$((BACKUP_COUNT - PGDUMP_BACKUP_RETENTION))
    EXCESS_FILES=$(find "${PGDUMP_BACKUP_DIR}" -maxdepth 1 -name "${DB_NAME}_*" -not -name "*_latest" | sort | head -n "${EXCESS_COUNT}")

    for file in ${EXCESS_FILES}; do
        if [ -d "${file}" ]; then
            rm -rf "${file}"
        else
            rm -f "${file}"
        fi
        log_info "已删除旧备份：${file}"
    done

    log_success "清理完成，已删除 ${EXCESS_COUNT} 个旧备份"
else
    log_info "当前备份数量不超过保留数量，无需清理"
fi

# 显示执行时间
end_timer

log_info "pg_dump 备份脚本执行完成"
exit 0
